home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) 1990 Free Software Foundation, Inc.
-
- This file is part of Oleo, the GNU Spreadsheet.
-
- Oleo is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 1, or (at your option)
- any later version.
-
- Oleo is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Oleo; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
- #include "funcdef.h"
-
- #include <fcntl.h>
- #include <errno.h>
- #include <ctype.h>
-
- #ifdef __TURBOC__
- #include <conio.h>
- #include <stdarg.h>
- #include <stdio.h>
-
- #define COLS 80
- #define LINES 24
-
- #define endwin() clrscr()
- #define initscr()
- #define scrollok(x,y)
- #define cbreak()
- #define noecho()
- #define nonl()
- #define nl()
- #define refresh()
- #define mvaddch(r,c,ch) move(r,c),addch(ch)
- #define mvaddstr(r,c,st) move(r,c),addstr(st)
- #define clear() clrscr()
- #define clrtoeol() clreol()
- #define addstr(str) cputs(str)
- #define addch(ch) putch(ch)
- #define move(y,x) gotoxy(x+1,y+1)
- #define getyx(nul,yy,xx) yy=wherey()-1,xx=wherex()-1
- #define delch() movetext(col+2,1,COLS,1,col+1,1),puttext(80,1,80,1,blank_text)
- #define insch(ch) movetext(col,1,COLS-1,1,col+1,1),putch(ch)
- #define standout() textattr(0x7<<4)
- #define standend() textattr(0x7)
- #define beep() putchar('\007')
- #define stdscr 0
- static void hack_standout EXT4(int, int, int, int);
- static char blank_text[] = { ' ', 0x07 };
- static void printw();
-
- #else
- #undef USG
- #undef NULL
- #include <curses.h>
-
- extern void tputs();
-
- extern int wclear();
- extern int wrefresh();
- extern int endwin();
- extern int wmove();
- extern int wclrtoeol();
- extern int printw();
- extern int wdelch();
- extern int waddch();
- extern int winsch();
- extern int waddstr();
- #ifndef amiga
- extern int wstandout();
- extern int wstandend();
- #endif
- static void beep();
-
- #endif
- #include "sysdef.h"
-
- #include "global.h"
- #include "cell.h"
- #include "kbd.h"
-
- /* This must agree with io_term.c */
- struct line {
- int alloc;
- char *buf;
- };
-
- /* Window flags:
- 0x01 Locked horizontally
- 0x02 Locked vertically
- 0x04 Page Horizontally
- 0x08 Page Vertically
- 0x10 Edges disabled
- 0x20 Edges standout
- */
- #define WIN_LCK_HZ 0x01
- #define WIN_LCK_VT 0x02
- #define WIN_PAG_HZ 0x04
- #define WIN_PAG_VT 0x08
- #define WIN_EDGES 0x10
- #define WIN_EDGE_REV 0x20
-
- #define MIN_WIN_HEIGHT (cwin->win_flags&WIN_EDGES ? 2 : 1)
- #define MIN_WIN_WIDTH (cwin->win_flags&WIN_EDGES ? 6 : 1)
-
- struct window {
- struct rng screen; /* Cells that are onscreen in this
- window */
- VOIDSTAR *win_slops; /* Slops in this window */
- int win_over; /* Where the data in this window starts */
- int win_down; /* on the screen. */
-
- int win_flags; /* Various flags */
-
- /* -1 if this window isn't linked to any others, else
- contains the index into wins of the window this one is
- linked to */
- int win_linked;
-
- /* Number of lines of spreadsheet that can fit in this window.
- This only changes when the screen is resized,
- win->flags&WIN_EDGES changes, or a window is either
- created or destroyed */
- int numr;
-
- /* Number of text columns that can fit in this window.
- This changes when the screen is resized,
- win->flags&WIN_EDGES changes, a window is created or
- destoryed, or win->lh_wid changes. In the last case
- win->numc+win->lh_wid remains a constant. */
- int numc;
-
- /* Number of characters taken up by the row numbers at the
- left hand edge of the screen. Zero if edges is
- win->flags&WIN_EDGES is off (by definition). Seven (or
- five) if win->flags&WIN_PAG_HZ (to make things easier).
- Ranges between three "R9 " to seven "R32767 " depending on
- the number of the highest row on the screen. */
- int lh_wid;
-
- /* Cursor row/column in this window */
- /* Note that the external variables curow, cucol are used for
- the currently active cursor position, so if you want
- cwin->curow and cwin->cucol to be accurate, you have to
- set them yourself. */
- CELLREF curow,cucol;
- };
-
- #define LINE_MIN 28
-
- /* in io_utils.c */
- extern void flush_slops EXT1(VOIDSTAR);
- extern int find_slop EXT5(VOIDSTAR, CELLREF, CELLREF, CELLREF *, CELLREF *);
- extern void kill_slop EXT4(VOIDSTAR, CELLREF, CELLREF, CELLREF);
- extern void change_slop EXT6(VOIDSTAR, CELLREF, CELLREF, CELLREF, CELLREF, CELLREF);
- extern void set_slop EXT4(VOIDSTAR *, CELLREF, CELLREF, CELLREF);
-
- extern char *print_cell EXT1(CELL *);
- extern char *adjust_prc EXT5(char *, CELL *, int, int, int);
-
- extern char *cell_value_string EXT2(CELLREF, CELLREF);
-
- /* in io_term.c */
- extern void set_line EXT2(struct line *,char *);
- extern int get_chr EXT0();
- extern int global_cmd EXT1(int);
-
- extern struct keymap main_map;
- extern struct keymap meta_map[];
- extern int topclear;
- extern CELLREF mkrow,mkcol;
- extern CELLREF setrow,setcol;
- extern unsigned int how_many;
- extern const int rowmagic[],colmagic[];
- #ifdef TEST
- extern int dbg_do_stderr;
- #endif
-
- /* in regions.c */
- extern void set_rng EXT5(struct rng *,CELLREF, CELLREF, CELLREF, CELLREF);
-
- void cur_status EXT0();
- void pr_cell EXT3(CELLREF, CELLREF, CELL *);
- void set_numcols EXT2(struct window *, CELLREF);
- void disp_scrn EXT0();
-
- static void find_nonzero_width EXT1(struct window *);
- static void hide_cell_cursor EXT0();
- static void display_cell_cursor EXT0();
-
- static void recenter_window EXT1(struct window *);
- static void pr_cell_win EXT4(struct window *, CELLREF, CELLREF, CELL *);
-
- /* Constants */
- const char numb_oflo[] ="\
- ##############################################################################\
- ##############################################################################\
- ##############################################################################\
- ######";
-
-
- static int nwin;
- static struct window *wins;
- static struct window *cwin;
-
- int status = 2;
- int input = 1;
-
- int redrew = 0;
- int textout = 0;
-
- #define TOPLN 0x2
- #undef CTRL
- #define CTRL(X) ((X)&037)
- #define META(X) ((X)|0200)
-
- #define L_TOGGLE_OVER 0
- #define L_BEG_LINE 1
- #define L_END_LINE 2
- #define L_BK_CHR 3
- #define L_BK_WORD 4
- #define L_BK_DEL_CHR 5
- #define L_BK_DEL_WORD 6
- #define L_BK_DEL_END 7
- #define L_FW_CHR 8
- #define L_FW_WORD 9
- #define L_FW_DEL_CHR 10
- #define L_FW_DEL_WORD 11
- #define L_FW_DEL_END 12
- #define L_FINISH 13
- #define L_INS_EXPR 14
- #define L_INS_VAL 15
- #define L_INS_REL 16
- #define L_INS_ABS 17
- #define L_INS_CHR 18
-
- struct cmd_func edit_funcs[] = {
- { "toggle-over-write", 0, TOPLN, 0 },
- { "cursor-begin-line", 0, TOPLN, 0 },
- { "cursor-end-line", 0, TOPLN, 0 },
- { "cursor-back-char", "n", TOPLN, 0 },
- { "cursor-back-word", "n", TOPLN, 0 },
- { "delete-prev-char", "n", TOPLN, 0 },
- { "delete-prev-word", "n", TOPLN, 0 },
- { "delete-to-start", 0, TOPLN, 0 },
- { "cursor-fwd-char", "n", TOPLN, 0 },
- { "cursor-fwd-word", "n", TOPLN, 0 },
- { "delete-next-char", "n", TOPLN, 0 },
- { "delete-next-word", "n", TOPLN, 0 },
- { "delete-to-end", 0, TOPLN, 0 },
- { "finish-line", 0, TOPLN, 0 },
- { "insert-cell-expression",0, TOPLN, 0 },
- { "insert-cell-value", 0, TOPLN, 0 },
- { "insert-rel-ref", 0, TOPLN, 0 },
- { "insert-abs-ref", 0, TOPLN, 0 },
- { "insert-character", "T", TOPLN, 0 },
- { 0, 0, 0, 0 }
- };
-
- static struct key edit_keys[] = {
- { 1, L_BEG_LINE }, /* ^A */
- { 1, L_BK_CHR },
- { 0, UNBOUND },
- { 1, L_FW_DEL_CHR },
- { 1, L_END_LINE }, /* ^E */
- { 1, L_FW_CHR },
- { 0, UNBOUND },
- { 1, L_BK_DEL_CHR },
- { 0, UNBOUND }, /* ^I */
- { 1, L_FINISH },
- { 1, L_FW_DEL_END },
- { 0, UNBOUND },
- { 1, L_FINISH }, /* ^M */
- { 0, UNBOUND },
- { 1, L_TOGGLE_OVER },
- { 0, UNBOUND },
- { 0, UNBOUND }, /* ^Q */
- { 0, UNBOUND },
- { 0, UNBOUND },
- { 0, UNBOUND },
- { 1, L_BK_DEL_END }, /* ^U */
- { 0, UNBOUND },
- { 0, UNBOUND },
- { 0, UNBOUND },
- { 0, UNBOUND },
- { 0, UNBOUND },
- { 255, 3 }
- };
- static struct key edit_1_keys[] = {
- { 1, L_INS_CHR }
- };
- static struct key edit_2_keys[] = {
- { 1, L_BK_DEL_CHR }
- };
-
- struct keymap edit_map[] = {
- {
- &edit_map[1], 0, 0, 1,
- CTRL('A'), CTRL('['),
- &edit_keys[0]
- }, {
- &edit_map[2], 0, 1, 1,
- ' ', '~',
- &edit_1_keys[0]
- },{
- &main_map, 1, 0, 1,
- '\177', '\177',
- &edit_2_keys[0]
- }
- };
-
- /* Beginning of the edit meta-keymap This is a sparse keymap */
- static struct key emk3[] = {
- { 1, L_BK_DEL_WORD }
- };
- static struct key emk2[] = {
- { 1, L_INS_REL },
- { 0, UNBOUND },
- { 0, UNBOUND },
- { 0, UNBOUND },
- { 1, L_INS_VAL }
- };
- static struct key emk1[] = {
- { 1, L_INS_ABS },
- { 1, L_BK_WORD },
- { 0, UNBOUND },
- { 1, L_FW_DEL_WORD },
- { 1, L_INS_EXPR },
- { 1, L_FW_WORD },
- };
-
- struct keymap edit_meta_map[] = {
- {
- &edit_meta_map[1], 0, 0, 0,
- CTRL('H'), CTRL('H'),
- &emk3[0]
- },{
- &edit_meta_map[2], 0, 0, 0,
- 'A', 'F',
- &emk1[0]
- },{
- &edit_meta_map[3], 0, 0, 0,
- 'R', 'V',
- &emk2[0]
- },{
- &edit_meta_map[4], 0, 0, 0,
- 'a', 'f',
- &emk1[0]
- },{
- &edit_meta_map[5], 0, 0, 0,
- 'r', 'v',
- &emk2[0]
- },{
- &meta_map[0], 1, 0, 0,
- '\177', '\177',
- &emk3[0]
- }
-
- };
-
- void
- open_display FUN1(int,c)
- {
- extern unsigned short print_width;
-
- initscr();
- scrollok(stdscr,0);
- #if !defined(__TURBOC__) && !defined(SYSV) && !defined(AMIGA)
- if(c || !strncmp(getenv("TERM"),"xterm",5)) {
- extern int stty EXT2(int, struct sgttyb *);
-
- _tty.sg_ispeed=15;_tty.sg_ospeed=15;stty(_tty_ch,&_tty);
- }
- #endif
-
- cbreak();
- noecho();
- nonl();
-
- /* Must be after initscr() */
- print_width=COLS;
- nwin=1;
- wins=cwin=ck_malloc(sizeof(struct window));
- cwin->win_slops=(void *)0;
- wins->win_over=0;
- wins->win_down=3;
- /* wins->win_edges=1; */
- wins->win_flags= WIN_EDGES|WIN_EDGE_REV;
- wins->win_linked= -1;
- wins->numc=COLS;
- wins->numr=LINES-3;
- wins->lh_wid=0;
- curow=wins->curow=MIN_ROW;
- cucol=wins->cucol=MIN_COL;
- }
-
- void
- close_display FUN0()
- {
- clear();
- refresh();
- (void)endwin();
- }
-
- void
- clear_top_before FUN0()
- {
- textout=0;
- if(topclear==2) {
- move(input-1,0);
- clrtoeol();
- topclear=0;
- }
- move(0,0);
- }
-
- void
- clear_top_after FUN0()
- {
- move(input-1,0);
- clrtoeol();
- topclear=0;
- }
-
- void
- redisp FUN0()
- {
- refresh();
- }
-
- static int nline;
- static int save_auto;
- extern int auto_recalc;
-
- void
- text_start FUN0()
- {
- clear();
- redisp();
- nline=0;
- save_auto=auto_recalc;
- auto_recalc=0;
- redrew++;
- }
-
- void
- text_line FUN1N(char *,ptr)
- {
- va_list ap;
- char sav;
- char buf[1000];
-
- var_start(ap,ptr);
- vsprintf(buf,ptr,ap);
- va_end(ap);
- ptr=buf;
-
- for(;;) {
- if(nline==LINES-1) {
- move(nline,0);
- addstr("Press a key to to proceed: ");
- refresh();
- (void)get_chr();
- clear();
- nline=0;
- }
- move(nline++,0);
- if(strlen(ptr)<=COLS) {
- addstr(ptr);
- break;
- }
- sav=ptr[COLS];
- ptr[COLS]='\0';
- addstr(ptr);
- ptr[COLS]=sav;
- refresh();
- ptr+=COLS;
- }
- }
- void
- text_finish FUN0()
- {
-
- if(nline!=0) {
- move(nline,0);
- addstr("Press a key to continue: ");
- refresh();
- (void)get_chr();
- }
- auto_recalc=save_auto;
- disp_scrn();
- }
-
- /* Return zero on success,
- one on empty input,
- and two on abort */
- int
- get_inp_line FUN2(char *,prompt, struct line *,line)
- {
- static int over; /* Overwrite or insert */
-
- char *ptr; /* Current position in the line */
- char *sptr; /* Start of the line */
- char *eptr; /* End of the line */
- int line_len; /* length of the line */
-
- int col = 0; /* Current cursor column */
- int plen; /* Length of the prompt */
-
- int domove = 0;
- int doscroll = 0;
-
- int c;
- int sfilled;
-
- char *in_str;
- int n;
- int do_free;
- char vbuf[50];
- extern char *macro_func_arg;
- extern struct cmd_func *cur_cmd;
- extern int cur_chr;
- extern unsigned char cur_vector;
-
- #define BUFFER 10
-
- #define MORE(bytes) \
- line_len+=bytes; \
- line->buf=ck_realloc(sptr,line_len+1); \
- eptr= eptr-sptr + line->buf; \
- ptr= ptr-sptr + line->buf; \
- sptr= line->buf; \
-
- #define KILLCH() \
- { \
- if(ptr!=eptr) { \
- char *tptr; \
- for(tptr=ptr;tptr<=eptr;tptr++) \
- tptr[-1]= tptr[0]; \
- } \
- --ptr; \
- --eptr; \
- --sfilled; \
- --col; \
- if(col<BUFFER) \
- doscroll++; \
- else if(!doscroll) { \
- move(input-1,col); \
- delch(); \
- if(eptr-sptr+plen>=COLS && ptr+(COLS-1-col)<eptr) { \
- mvaddch(input-1,COLS-1,ptr[COLS-1-col]);\
- domove++; \
- } \
- } \
- }
-
- topclear=2;
-
- if(macro_func_arg) {
- set_line(line,macro_func_arg);
- macro_func_arg=0;
- return 0;
- }
- if(!line->alloc) {
- line->alloc=LINE_MIN;
- line->buf=ck_malloc(LINE_MIN);
- line->buf[0]='\0';
- }
- line_len=line->alloc-1; /* Leave room for the NULL */
- sptr=line->buf;
-
- sfilled=strlen(sptr);
- plen=strlen(prompt)+3;
- ptr=sptr+sfilled;
- eptr=ptr;
- over=0;
-
- doscroll++;
- for(;;) {
- if(domove) {
- domove=0;
- if(col<BUFFER || col>COLS-BUFFER)
- doscroll++;
- else
- move(input-1,col);
- }
- if(doscroll) {
- doscroll=0;
- redrew=0;
- if(textout==2) {
- /* [MORE] the error msg, so the luser has
- a chance to see it. . . */
- mvaddstr(input-1,COLS-7,"[MORE]");
- (void)get_chr();
- }
- textout=0;
- move(input-1,0);
- clrtoeol();
- if(plen + (ptr-sptr)<COLS-BUFFER) {
- *eptr=0;
- printw("%s: %.*s",prompt,COLS-plen,sptr);
- col=plen+(ptr-sptr);
- } else {
- char *p;
- p=sptr+COLS-2*BUFFER-plen;
- while(ptr-p>=COLS-BUFFER)
- p+=COLS-2*BUFFER;
- *eptr=0;
- printw("%.*s",COLS,p);
- col=ptr-p;
- }
- move(input-1,col);
- }
- if(how_many!=1) {
- how_many=1;
- cur_status();
- move(input-1,col);
- }
- map_chr(EDIT_MAP);
- swtch:
- if(cur_vector!=1) {
- n=global_cmd(EDIT_MAP);
- if(redrew || textout)
- doscroll++;
- if(n==-3) {
- *eptr++='\0';
- return 2;
- } else if(n==-2) {
- beep();
- beep();
- } else if(n>=0)
- goto swtch;
- continue;
- }
- switch(cur_cmd-edit_funcs) {
- case L_BEG_LINE:
- col-=ptr-sptr;
- ptr=sptr;
- domove++;
- break;
-
- case L_BK_CHR:
- for(n=0;ptr!=sptr && n<how_many;n++) {
- --ptr;
- --col;
- }
- domove++;
- break;
-
- case L_BK_WORD:
- for(n=0;ptr!=sptr && n<how_many;n++) {
- while(ptr!=sptr && !isalnum(ptr[-1])) {
- --ptr;
- --col;
- }
- while(ptr!=sptr && isalnum(ptr[-1])) {
- --ptr;
- --col;
- }
- }
- domove++;
- break;
-
- case L_FW_DEL_CHR:
- for(n=0;ptr!=eptr && n<how_many;n++) {
- ptr++;
- col++;
- KILLCH()
- }
- break;
-
- case L_FW_DEL_WORD:
- for(n=0;ptr!=eptr && n<how_many;n++) {
- while(ptr!=eptr && !isalnum(ptr[0])) {
- ptr++;
- col++;
- KILLCH()
- }
- while(ptr!=eptr && isalnum(ptr[0])) {
- ptr++;
- col++;
- KILLCH()
-
- }
- }
- break;
-
- case L_END_LINE:
- col+=eptr-ptr;
- ptr=eptr;
- domove++;
- break;
-
- case L_FW_CHR:
- for(n=0;ptr!=eptr && n<how_many;n++) {
- col++;
- ptr++;
- }
- domove++;
- break;
-
- case L_FW_WORD:
- for(n=0;ptr!=eptr && n<how_many;n++) {
- while(ptr!=eptr && !isalnum(ptr[0])) {
- col++;
- ptr++;
- }
- while(ptr!=eptr && isalnum(ptr[0])) {
- col++;
- ptr++;
- }
- }
- domove++;
- break;
-
- case L_FW_DEL_END:
- eptr=ptr;
- clrtoeol();
- break;
-
- case L_TOGGLE_OVER:
- over= !over;
- break;
-
- case L_BK_DEL_WORD:
- for(n=0;ptr!=sptr && n<how_many;n++) {
- while(ptr!=sptr && !isalnum(ptr[-1]))
- KILLCH()
-
- while(ptr!=sptr && isalnum(ptr[-1]))
- KILLCH()
- }
-
- break;
-
- case L_BK_DEL_END:
- while(ptr!=sptr)
- KILLCH()
- break;
-
- case L_BK_DEL_CHR:
- for(n=0;ptr!=sptr && n<how_many;n++)
- KILLCH()
- break;
-
-
- case L_FINISH:
- *eptr++='\0';
- textout=1;
- return eptr-sptr==1 ? 1 : 0;
-
- case L_INS_EXPR:
- {
- CELL *cp;
-
- if(!(cp=find_cell(curow,cucol)))
- break;
- in_str=decomp(curow,cucol,cp);
- do_free=1;
- }
- goto insert_string;
-
- case L_INS_VAL:
- in_str=cell_value_string(curow,cucol);
- do_free=0;
- goto insert_string;
-
- case L_INS_REL:
- #ifdef A0_REFS
- if(mkrow!=NON_ROW) {
- struct rng r;
-
- set_rng(&r,curow,cucol,mkrow,mkcol);
- in_str=range_name(&r);
- } else
- in_str=cell_name(curow,cucol);
- #else
- if(mkrow!=NON_ROW) {
- switch( ((curow==setrow)<<3)
- + ((mkrow==setrow)<<2)
- + ((cucol==setcol)<<1)
- + (mkcol==setcol)) {
- case 0:
- case 1:
- case 2:
- case 4:
- case 5:
- case 6:
- case 8:
- case 9:
- case 10:
- sprintf(vbuf,"r[%+d:%+d]c[%+d:%+d]",
- (curow < mkrow ? curow : mkrow) - setrow,
- (curow < mkrow ? mkrow : curow) - setrow,
- (cucol < mkcol ? cucol : mkcol) - setcol,
- (cucol < mkcol ? mkcol : cucol) - setcol);
- break;
- case 3:
- case 7:
- case 11:
- sprintf(vbuf,"r[%+d:%+d]c",
- (curow < mkrow ? curow : mkrow) - setrow,
- (curow < mkrow ? mkrow : curow) - setrow);
- break;
- case 12:
- case 14:
- case 13:
- sprintf(vbuf,"rc[%+d:%+d]",
- (cucol < mkcol ? cucol : mkcol) - setcol,
- (cucol < mkcol ? mkcol : cucol) - setcol);
- break;
- case 15:
- strcpy(vbuf,"rc");
- break;
- #ifdef TEST
- default:
- panic("Unknown value");
- #endif
- }
- } else {
- switch(((curow==setrow)<<1) + (cucol==setcol)) {
- case 0:
- sprintf(vbuf,"r[%+d]c[%+d]",curow-setrow,cucol-setcol);
- break;
- case 1:
- sprintf(vbuf,"r[%+d]c",curow-setrow);
- break;
- case 2:
- sprintf(vbuf,"rc[%+d]",cucol-setcol);
- break;
- case 3:
- strcpy(vbuf,"rc");
- break;
- #ifdef TEST
- default:
- panic("huh what");
- #endif
- }
- }
- in_str=vbuf;
- #endif
- do_free=0;
- goto insert_string;
-
- case L_INS_ABS:
- /* Insert current cell/range name as an absolute reference */
- #ifdef A0_REFS
- if(mkrow!=NON_ROW)
- sprintf(vbuf,"$%s$%u:$%s:$%u",col_to_str(cucol),curow,col_to_str(mkcol),mkrow);
- else
- sprintf(vbuf,"$%s$%u",col_to_str(cucol), curow);
- in_str=vbuf;
- #else
- if(mkrow!=NON_ROW) {
- struct rng r;
-
- set_rng(&r,curow,cucol,mkrow,mkcol);
- in_str=range_name(&r);
- } else
- in_str=cell_name(curow,cucol);
- #endif
- do_free=0;
-
- insert_string:
- c=strlen(in_str);
- if((sfilled + (over ? c + (ptr-eptr) : c)) >= line_len) {
- n= over ? c + (ptr-eptr) : c;
- if(n<LINE_MIN)
- n=LINE_MIN;
- MORE(n);
- }
- if(over) {
- if(ptr+c>eptr) {
- sfilled+=(ptr+c)-eptr;
- eptr=ptr+c;
- }
- } else {
- if(ptr!=eptr) {
- char *tptr;
-
- for(tptr=eptr;tptr>=ptr;--tptr)
- tptr[c]=tptr[0];
- }
- eptr+=c;
- sfilled+=c;
- }
- bcopy(in_str,ptr,c);
- ptr+=c;
- if(col+c>=COLS-BUFFER) {
- doscroll++;
- } else {
- col+=c;
- if(!over && ptr!=eptr) {
- #ifdef __TURBOC__
- movetext(col-c,1,COLS-c,1,col,1);
- #else
- while(c--)
- insch(' ');
- #endif
- }
- addstr(in_str);
- }
- if(do_free)
- decomp_free();
- break;
-
- case L_INS_CHR:
- if((sfilled+how_many + (over ? (ptr-eptr) : (0))) >= line_len) {
- n = over ? how_many+(ptr-eptr) : how_many;
- if(n<LINE_MIN)
- n=LINE_MIN;
- MORE(n);
- }
- if(over) {
- if(ptr+how_many>eptr) {
- sfilled+=(ptr+how_many)-eptr;
- eptr=ptr+how_many;
- }
- } else {
- if(ptr!=eptr) {
- char *tptr;
-
- for(tptr=eptr;tptr>=ptr;--tptr)
- tptr[how_many]=tptr[0];
- }
- eptr+=how_many;
- sfilled+=how_many;
- }
- for(n=0;n<how_many;n++)
- *ptr++=cur_chr;
-
- if(col+how_many>=COLS-BUFFER) {
- doscroll++;
- } else if(over || ptr==eptr) {
- col+=how_many;
- for(n=0;n<how_many;n++)
- addch(cur_chr);
- } else {
- col+=how_many;
- for(n=0;n<how_many;n++) {
- insch(cur_chr);
- move(input-1,col);
- }
- }
- break;
- }
- }
- #undef KILLCH
- #undef BUFFER
- #undef MORE
- }
-
- /* External interface to window routines */
- /* Create a new window by splitting the current one. */
- void
- open_window FUN1(char *,text)
- {
- int hv;
- int where;
- int tmp;
- struct window *win;
-
- while(*text==' ')
- text++;
-
- if(*text=='h' || *text=='H') {
- hv=1;
- } else if(*text=='v' || *text=='V') {
- hv=0;
- } else {
- error_msg("Open 'h'orizontal or 'v'ertical window, not '%s'",text);
- return;
- }
- where=atoi(text+1);
-
- if( (!hv && ( where<MIN_WIN_WIDTH
- || cwin->numc-where<MIN_WIN_WIDTH))
- || ( hv && ( where<MIN_WIN_HEIGHT
- || cwin->numr-where<MIN_WIN_HEIGHT))) {
- error_msg("Window won't fit!");
- return;
- }
- nwin++;
- tmp=cwin-wins;
-
- wins=ck_realloc(wins,nwin*sizeof(struct window));
- win= &wins[nwin-1];
- win->win_slops=(void *)0;
- cwin= &wins[tmp];
- win->win_over=cwin->win_over + (hv ? 0 : where) - cwin->lh_wid;
- win->win_down=cwin->win_down + (hv ? where : 0);
- win->win_flags = cwin->win_flags;
- win->win_linked= -1;
- win->lh_wid=0;
- win->numc=cwin->numc + cwin->lh_wid + (hv ? 0 : -where);
- win->numr=cwin->numr + (hv ? -where : 0);
- win->curow=curow;
- win->cucol=cucol;
- set_numcols(win,curow);
- cwin->numc-=(hv ? 0 : win->numc+win->lh_wid);
- cwin->numr-=(hv ? (win->numr+(win->lh_wid?1:0)) : 0);
- cwin->curow=curow;
- cwin->cucol=cucol;
- hide_cell_cursor();
- win=cwin;
- cwin= &wins[nwin-1];
- recenter_window(cwin);
- recenter_window(win);
- disp_scrn();
- }
-
- static void do_close_window FUN1(int, num)
- {
- int n;
- struct window *win,*kwin;
- int nlf,nrt,nup,nbl;
- int klo,kho,kld,khd;
- int lo,ho,ld,hd;
- struct tmp {
- int l,
- r,
- u,
- b;
- } *tmpptr;
- void recenter_all_win EXT0();
-
- tmpptr=ck_malloc(sizeof(struct tmp)*nwin);
-
- kwin= &wins[num];
- nlf=nrt=nup=nbl=0;
- klo=kwin->win_over-kwin->lh_wid;
- kho=kwin->win_over+kwin->numc-1;
- kld=kwin->win_down-(kwin->lh_wid?1:0);
- khd=kwin->win_down+kwin->numr-1;
-
- for(win=wins;win<&wins[nwin];win++) {
- lo=win->win_over-win->lh_wid;
- ho=win->win_over+win->numc-1;
- ld=win->win_down-(win->lh_wid?1:0);
- hd=win->win_down+win->numr-1;
-
- /* Match to the left ? */
- if(lo==kho+1) {
- if(ld>=kld && hd<=khd)
- tmpptr[nrt++].r=win-wins;
- else if(hd>=kld && ld<=khd)
- nrt= nwin;
- }
- else if(ho==klo-1) {
- if(ld>=kld && hd<=khd)
- tmpptr[nlf++].l=win-wins;
- else if(hd>=kld && ld<=khd)
- nlf= nwin;
- }
- else if(ld==khd+1) {
- if(lo>=klo && ho<=kho)
- tmpptr[nbl++].b=win-wins;
- else if(ho>=kho && lo<=kho)
- nbl= nwin;
- }
- else if(hd==kld-1) {
- if(lo>=klo && ho<=kho)
- tmpptr[nup++].u=win-wins;
- else if(ho>=kho && lo<=kho)
- nup= nwin;
- }
-
- }
- if(nrt==0)
- nrt=nwin;
- if(nlf==0)
- nlf=nwin;
- if(nbl==0)
- nbl=nwin;
- if(nup==0)
- nup=nwin;
- if(nrt<=nlf && nrt<=nbl && nrt<=nup) {
- for(n=0;n<nrt;n++) {
- wins[tmpptr[n].r].numc+=kwin->lh_wid+kwin->numc;
- wins[tmpptr[n].r].win_over-=kwin->lh_wid+kwin->numc;
- }
- } else if(nlf<=nbl && nlf<=nup) {
- for(n=0;n<nlf;n++)
- wins[tmpptr[n].l].numc+=kwin->lh_wid+kwin->numc;
- } else if(nbl<=nup) {
- for(n=0;n<nbl;n++) {
- wins[tmpptr[n].b].numr+=kwin->numr+(kwin->lh_wid ? 1 : 0);
- wins[tmpptr[n].b].win_down-=kwin->numr+(kwin->lh_wid ? 1 : 0);
- }
- } else {
- for(n=0;n<nup;n++)
- wins[tmpptr[n].u].numr+=kwin->numr+(kwin->lh_wid ? 1 : 0);
- }
- if(kwin==cwin && kwin!= wins)
- --cwin;
- if(cwin==&wins[nwin-1])
- --cwin;
- while(kwin< &wins[nwin]) {
- *kwin= kwin[1];
- kwin++;
- }
- --nwin;
- recenter_all_win();
- return;
- }
-
- void
- close_window FUN1(char *,text)
- {
- int num;
-
- num=atoi(text)-1;
- if(num<0 || num>=nwin) {
- error_msg("Window %s?",text);
- return;
- }
- if(nwin==1) {
- error_msg("You can't close the last window!");
- return;
- }
- do_close_window(num);
- }
-
- void
- goto_window FUN1(char *,text)
- {
- int n;
-
- n=atoi(text)-1;
- if(n<0 || n>nwin) {
- error_msg("Window %s doesn't exist.",text);
- return;
- }
- hide_cell_cursor();
- cwin->curow=curow;
- cwin->cucol=cucol;
- cwin= &wins[n];
- curow=cwin->curow;
- cucol=cwin->cucol;
- display_cell_cursor();
- }
-
- static int locmp FUN2(struct window **,a, struct window **,b)
- {
- return (*a)->win_down-(*b)->win_down;
- }
- static int hicmp FUN2(struct window **,a, struct window **,b)
- {
- return ((*a)->win_down+(*a)->numr)-((*b)->win_down+(*b)->numr);
- }
-
- /* How this works: First figure out how many lines are now avaliable for
- sheet data. Then squeeze/stretch the windows to fit that space. . . */
-
- static void resize_screen FUN0()
- {
- int n;
- int nlines;
- int firstln;
- /* int shifted; */
- int lo,sq,hi;
- struct window **t;
-
- if(input<LINES/2) {
- if(status>LINES/2) {
- nlines=status-input-1;
- firstln=input+1;
- } else {
- firstln=1+input>status?input:status;
- nlines=LINES-firstln;
- }
- } else if(status<LINES/2) {
- nlines=input-status;
- firstln=status+1;
- } else {
- firstln=1;
- nlines=(input>status?status:input)-1;
- }
-
- t=ck_malloc(nwin*sizeof(struct window *));
- for(n=0;n<nwin;n++)
- t[n]= &wins[n];
- qsort(t,nwin,sizeof(struct window *),hicmp);
- hi=t[0]->win_down+t[0]->numr;
- sq=firstln+nlines-hi;
- for(n=0;n<nwin && hi==t[n]->win_down+t[0]->numr;n++) {
- t[n]->numr-=sq;
- }
- qsort(t,nwin,sizeof(struct window *),locmp);
- lo=t[0]->win_down;
- sq=firstln-lo+((t[0]->win_flags&WIN_EDGES)?1:0);
- for(n=0;n<nwin && t[n]->win_down==lo;n++) {
- t[n]->numr-=sq;
- t[n]->win_down=firstln+((t[0]->win_flags&WIN_EDGES)?1:0);
- }
- cwin->curow=curow;
- cwin->cucol=cucol;
- for(n=0;n<nwin;n++) {
- if(wins[n].numr<=0) {
- do_close_window(n);
- n--;
- } else
- recenter_window(&wins[n]);
- }
- disp_scrn();
- }
-
- #if 0
- static void shift_screen FUN1(int, by)
- {
- int n;
-
- for(n=0;n<nwin;n++)
- wins[n].win_down+=by;
- disp_scrn();
- }
- #endif
-
- int
- set_window_option FUN2(int,set_opt, char *,text)
- {
- int n;
- static struct opt {
- char *text;
- int bits;
- } opts[] = {
- { "reverse", WIN_EDGE_REV },
- { "standout", WIN_EDGE_REV },
- { "page", WIN_PAG_HZ|WIN_PAG_VT },
- { "pageh", WIN_PAG_HZ },
- { "pagev", WIN_PAG_VT },
- { "lockh", WIN_LCK_HZ },
- { "lockv", WIN_LCK_VT }
- };
- if(set_opt && !strincmp(text,"status ",7)) {
- n=atoi(text+7);
- if(n>LINES || n<-LINES) {
- error_msg("%s?",text);
- return 1;
- }
- if(n<0)
- n=LINES+1+n;
- status=n;
- resize_screen();
- } else if(set_opt && !strincmp(text,"input ",6)) {
- n=atoi(text+6);
- if(n==0 || n>LINES || n<-LINES) {
- error_msg("%s?",text);
- return 1;
- }
- if(n<0)
- n=LINES+1+n;
- input=n;
- resize_screen();
- } else if(!strincmp(text,"link",4)) {
- if(set_opt) {
- n=atoi(text+4)-1;
- if(n<0 || n>nwin)
- error_msg("Can't '%s': window # out of range",text);
- else
- cwin->win_linked= n;
- } else
- cwin->win_linked= -1;
- } else if(set_opt && !stricmp(text,"unlink")) {
- cwin->win_linked= -1;
- } else if(!stricmp(text,"edges")) {
- if(set_opt) {
- if((cwin->win_flags&WIN_EDGES)==0) {
- if(cwin->numr<2 || cwin->numc<6)
- error_msg("Edges wouldn't fit!");
- cwin->win_flags|= WIN_EDGES;
- cwin->win_down++;
- cwin->numr--;
- /* set_numcols(cwin,cwin->screen.hr); */
- }
- } else {
- if(cwin->win_flags&WIN_EDGES) {
- cwin->win_flags&= ~WIN_EDGES;
- cwin->win_over-=cwin->lh_wid;
- cwin->numc+=cwin->lh_wid;
- cwin->lh_wid=0;
- cwin->win_down--;
- cwin->numr++;
- }
- }
-
- } else if(set_opt && !strincmp(text,"row ",4)) {
- text+=4;
- curow=astol(&text);
- } else if(set_opt && !strincmp(text,"col ",4)) {
- text+=4;
- cucol=astol(&text);
- } else {
- for(n=0;n<sizeof(opts)/sizeof(struct opt);n++) {
- if(!stricmp(text,opts[n].text)) {
- if(set_opt)
- cwin->win_flags|= opts[n].bits;
- else
- cwin->win_flags&= ~opts[n].bits;
- break;
- }
- }
- if(n==sizeof(opts)/sizeof(struct opt))
- return 0;
- }
- return 1;
- }
-
- void
- show_window_options FUN0()
- {
- int n;
- struct window *win;
-
- cwin->curow=curow;
- cwin->cucol=cucol;
- win= &wins[0];
- if(status)
- text_line("Status line at %d", status);
- else
- text_line("Status line disabled.");
- text_line("");
- for(n=0;n<nwin;n++) {
- text_line("Window #%d showing %s, with cursor at %s",
- n+1,
- range_name(&(win->screen)),
- cell_name(win->curow,win->cucol));
- text_line(" Options: %sedges (%sreverse)%s%s%s%s",
- win->win_flags&WIN_EDGES ? "" : "no",
- win->win_flags&WIN_EDGE_REV ? "" : "no",
- win->win_flags&WIN_PAG_HZ ? ", pageh" : "",
- win->win_flags&WIN_PAG_VT ? ", pagev" : "",
- win->win_flags&WIN_LCK_HZ ? ", lockh" : "",
- win->win_flags&WIN_LCK_VT ? ", lockv" : "");
- if(win->win_linked!=-1)
- text_line("Linked to window %d",win->win_linked+1);
- win++;
- }
- }
-
- #ifdef TEST
- void
- dbg_show_wins FUN0()
- {
- int n;
-
- for(n=0;n<nwin;n++) {
- text_line("Window %d",n);
- text_line(" screen %s slops %p flags %x linked %d",
- range_name(&(wins[n].screen)),wins[n].win_slops,wins[n].win_flags,
- wins[n].win_linked);
- text_line(" ov %d dn %d nr %d nc %d lh_wid %d pos %s",wins[n].win_over,wins[n].win_down,wins[n].numr,wins[n].numc,wins[n].lh_wid,cell_name(wins[n].curow,wins[n].cucol));
- text_line("");
- }
- }
- #endif
-
- void
- disp_scrn FUN0()
- {
- CELLREF cc,rr;
- int n,n1;
- CELL *cp;
- struct window *win;
-
- clear();
- redrew++;
- for(win=wins;win<&wins[nwin];win++) {
- if(win->lh_wid) {
- move(win->win_down-1,win->win_over-win->lh_wid);
- printw("#%*d ", win->lh_wid-2, 1+win-wins);
- if(win->win_flags&WIN_EDGE_REV)
- standout();
- cc=win->screen.lc;
- do {
- n=get_width(cc);
- if(n>win->numc)
- n=win->numc;
- if(n>1) {
- char *ptr;
- #ifdef A0_REFS
- ptr=col_to_str(cc);
- #else
- char buf[30];
-
- sprintf(buf,"C%u",cc);
- ptr=buf;
- #endif
- --n;
- n1=strlen(ptr);
- if(n<n1)
- printw("%.*s ",n,"###############");
- else {
- n1=(n-n1)/2;
- printw("%*s%-*s ",n1,"",n-n1,ptr);
- }
- } else if(n==1)
- addstr("#");
- } while(cc++<win->screen.hc);
-
- rr=win->screen.lr;
- do {
- move(rr+win->win_down-win->screen.lr,win->win_over-win->lh_wid);
- #ifdef A0_REFS
- printw("%-*d ",win->lh_wid-1,rr);
- #else
- printw("R%-*d",win->lh_wid-1,rr);
- #endif
- } while(rr++<win->screen.hr);
-
- if(win->win_flags&WIN_EDGE_REV)
- standend();
- }
- flush_slops(win->win_slops);
- find_cells_in_range(&(win->screen));
- while(cp=next_row_col_in_range(&rr,&cc))
- if(GET_TYP(cp))
- {
- pr_cell_win(win,rr,cc,cp);
- }
- }
- if(!(cp=find_cell(curow,cucol)) || !GET_TYP(cp))
- display_cell_cursor();
- cur_status();
- }
-
- void
- set_numcols FUN2(struct window *,win, CELLREF,hr)
- {
- int lh;
-
- if((win->win_flags&WIN_EDGES)==0)
- lh=0;
- #if BITS_PER_CELLREF>8
- else if((win->win_flags&WIN_PAG_HZ) || hr>=10000)
- lh=7;
- else if(hr>=1000)
- lh=6;
- else if(hr>=100)
- lh=5;
- #else
- else if((win->win_flags&WIN_PAG_HZ) || hr>=100)
- lh=5;
- #endif
- else if(hr>10)
- lh=4;
- else
- lh=3;
- win->win_over-=win->lh_wid-lh;
- win->numc+=win->lh_wid-lh;
- win->lh_wid=lh;
- }
-
- static void
- move_cursor_to FUN3(struct window *,win, CELLREF, r,CELLREF, c)
- {
- int cc;
- int cursor_col;
-
- cursor_col=win->win_over;
- for(cc=win->screen.lc;cc<c;cc++)
- cursor_col+=get_width(cc);
- move(win->win_down+r-win->screen.lr,cursor_col);
- }
-
- void
- pr_cell FUN3(CELLREF, r, CELLREF, c, CELL *, cp)
- {
- int xx,yy;
- struct window *win = (void *)0;
-
- getyx(stdscr,yy,xx);
- for(win=wins;win<&wins[nwin];win++) {
- if( r<win->screen.lr || r>win->screen.hr
- || c<win->screen.lc || c>win->screen.hc)
- continue;
-
- pr_cell_win(win,r,c,cp);
- }
- move(yy,xx);
- }
-
- static void
- pr_cell_win FUN4(struct window *,win, CELLREF, r, CELLREF, c, CELL *, cp)
- {
- int glowing;
- int lenstr;
- int j;
- int wid,wwid;
- char *ptr;
-
- wid=get_width(c);
- if(!wid)
- return;
- if(wid>win->numc)
- wid=win->numc;
- glowing = (r==curow && c==cucol && win==cwin);
-
- ptr=print_cell(cp);
- #ifdef TEST
- if(!ptr)
- panic("print_cell returned 0");
- #endif
- move_cursor_to(win,r,c);
- if(glowing)
- standout();
- j=GET_JST(cp);
- if(j==JST_DEF)
- j=default_jst;
- lenstr=strlen(ptr);
-
- if(lenstr<=wid-1) {
- CELLREF ccl,cch;
-
- if(j==JST_LFT)
- printw("%-*.*s",wid, wid-1,ptr);
- else if(j==JST_RGT)
- printw("%*.*s ",wid-1, wid-1,ptr);
- else if(j==JST_CNT) {
- wid=(wid-1)-lenstr;
- printw("%*s%*s ",(wid+1)/2+lenstr,ptr,wid/2,"");
- }
- #ifdef TEST
- else
- panic("Unknown justification");
- #endif
- if(glowing)
- standend();
-
- if(lenstr==0 && c>win->screen.lc && find_slop(win->win_slops,r,c-1,&ccl,&cch)) {
- CELLREF ccdl,ccdh;
-
- if(find_slop(win->win_slops, r,c,&ccdl,&ccdh) && ccdl==c) {
- kill_slop(win->win_slops, r,ccdl,ccdh);
- for(;ccdh!=ccdl;--ccdh)
- if(ccdh!=c && (wid=get_width(ccdh))) {
- move_cursor_to(win,r,ccdh);
- printw("%*s",wid,"");
- }
- }
- kill_slop(win->win_slops, r,ccl,cch);
- pr_cell(r,ccl,find_cell(r,ccl));
- } else if(find_slop(win->win_slops, r,c,&ccl,&cch)) {
- kill_slop(win->win_slops, r,ccl,cch);
- for(;cch!=ccl;--cch)
- if(cch!=c && (wid=get_width(cch))) {
- move_cursor_to(win,r,cch);
- printw("%*s",wid,"");
- }
- pr_cell(r,ccl,find_cell(r,ccl));
- }
- } else {
- CELLREF cc=c;
- CELL *ccp;
- CELLREF ccl,cch;
-
- for(wwid=wid;lenstr>wwid-1;wwid+=get_width(cc)) {
- if( ++cc>win->screen.hc
- || ( ccp=find_cell(r,cc))
- && GET_TYP(ccp)
- && ( GET_FMT(ccp)!=FMT_HID
- || ( GET_FMT(ccp)==FMT_DEF
- && default_fmt!=FMT_HID))) {
- --cc;
- break;
- }
- }
-
- if(lenstr>wwid-1)
- if(GET_TYP(cp)==TYP_FLT)
- ptr=adjust_prc(ptr,cp,wwid-1,wid-1,j);
- else if(GET_TYP(cp)==TYP_INT)
- ptr=(char *)numb_oflo;
-
- if(wwid==1) {
- addch(' ');
- if(glowing)
- standend();
- } else if(wwid==wid) {
- printw("%-*.*s ",wwid-1,wwid-1,ptr);
- if(glowing)
- standend();
- } else if(glowing) {
- printw("%.*s",wid,ptr);
- standend();
- printw("%-*.*s ",wwid-wid-1,wwid-wid-1,ptr+wid);
- } else if(r==curow && (cucol>c && cucol<=cc)) {
- CELLREF ctmp;
- int w_left;
- int w_here;
-
- w_left=wid;
- for(ctmp=c+1;ctmp<cucol;ctmp++)
- w_left+=get_width(ctmp);
- printw("%.*s",w_left,ptr);
- standout();
- w_here=get_width(cucol);
- if(wwid>w_left+w_here) {
- printw("%-*.*s",w_here,w_here,ptr+w_left);
- standend();
- printw("%-*.*s ",wwid-(w_left+w_here)-1,wwid-(w_left+w_here)-1,ptr+w_left+w_here);
- } else {
- printw("%-*.*s",w_here,w_here-1,ptr+w_left);
- standend();
- }
- } else
- printw("%-*.*s ",wwid-1,wwid-1,ptr);
-
- if(find_slop(win->win_slops, r,c,&ccl,&cch)) {
- change_slop(win->win_slops, r,ccl,cch,c,cc);
- for(;cch>cc;--cch)
- if(wid=get_width(cch)) {
- move_cursor_to(win,r,cch);
- printw("%*s",wid,"");
- }
- for(cch=c-1;cch>ccl;--cch)
- if(wid=get_width(cch)) {
- move_cursor_to(win,r,cch);
- printw("%*s",wid,"");
- }
- if(ccl!=c)
- pr_cell(r,ccl,find_cell(r,ccl));
- } else
- set_slop((VOIDSTAR *)(&(win->win_slops)), r,c,cc);
- }
- if(glowing)
- cur_status();
- }
- void
- cur_status FUN0()
- {
- CELL *cp;
- char *dec;
- char *ptr;
- static char hmbuf[40];
- int wid;
- int plen;
- int dlen;
- int yy,xx;
-
- if(!status)
- return;
- getyx(stdscr,yy,xx);
- move(status-1,0);
- wid=COLS-2;
-
- if(mkrow!=NON_ROW) {
- struct rng r;
-
- addch('*');
- --wid;
- set_rng(&r,curow,cucol,mkrow,mkcol);
- ptr=range_name(&r);
- } else
- ptr=cell_name(curow,cucol);
-
- addstr(ptr);
- wid-=strlen(ptr);
-
- if(how_many!=1) {
- sprintf(hmbuf," {%u}",how_many);
- addstr(hmbuf);
- wid-=strlen(hmbuf);
- }
-
- if((cp=find_cell(curow,cucol)) && cp->cell_formula) {
- dec=decomp(curow,cucol,cp);
- dlen=strlen(dec);
- } else {
- dec=0;
- dlen=0;
- }
-
- ptr=cell_value_string(curow,cucol);
- plen=strlen(ptr);
-
- if(dec) {
- wid-=4;
- if(dlen+plen>wid) {
- if(plen+3>wid)
- printw(" %.*s... [...]",wid-6,ptr);
- else
- printw(" %s [%.*s...]",ptr,wid-plen-3,dec);
- } else
- printw(" %s [%s]",ptr,dec);
- decomp_free();
- } else if(plen) {
- --wid;
- if(plen>wid)
- printw(" %.*s...",wid-3,ptr);
- else
- printw(" %s",ptr);
- }
-
- clrtoeol();
- move(yy,xx);
- }
-
- static void
- display_cell_cursor FUN0()
- {
- int cc;
- int cursor_row;
- int cursor_col;
- int cwid;
- #ifndef __TURBOC__
- int n;
- #endif
-
- cursor_col=cwin->win_over;
- for(cc=cwin->screen.lc;cc<cucol;cc++)
- {
- cursor_col+=get_width(cc);
- }
- cursor_row=cwin->win_down+curow-cwin->screen.lr;
- cwid=get_width(cucol);
- if(cwid>cwin->numc)
- cwid=cwin->numc;
- #ifdef __TURBOC__
- hack_standout(1,cursor_row,cursor_col,cwid);
- #else
- move(cursor_row,cursor_col);
- standout();
- for(n=cwid;n;n--)
- #ifdef A_STANDOUT
- addch(inch()|A_STANDOUT);
- #else
- addch(inch());
- #endif
- standend();
- #endif
- }
-
- static void
- hide_cell_cursor FUN0()
- {
- int cc;
- int cursor_row;
- int cursor_col;
- int cwid;
- #ifndef __TURBOC__
- int n;
- #endif
-
- cursor_col=cwin->win_over;
- for(cc=cwin->screen.lc;cc<cucol;cc++)
- {
- cursor_col+=get_width(cc);
- }
- cursor_row=cwin->win_down+curow-cwin->screen.lr;
- cwid=get_width(cucol);
- if(cwid>cwin->numc)
- cwid=cwin->numc;
- #ifdef __TURBOC__
- hack_standout(0,cursor_row,cursor_col,cwid);
- #else
- move(cursor_row,cursor_col);
- for(n=cwid;n;n--)
- #ifdef SYSV
- addch(inch()&~A_STANDOUT);
- #else
- addch(inch());
- #endif
- #endif
- }
-
- #ifdef __TURBOC__
- static void
- hack_standout FUN4(int,standp, int,rown, int,coln, int,cols)
- {
- char buf[COLS*2];
- char *ptr;
- int n;
-
- standp = standp ? 0x7<<4 : 0x7;
- rown++;
- coln++;
- gettext(coln,rown,coln+cols-1,rown,buf);
- ptr=buf+1;
- n=cols;
- while(n--) {
- *ptr= standp;
- ptr+=2;
- }
- puttext(coln,rown,coln+cols-1,rown,buf);
- }
-
- static void
- printw FUN1N(char *,str)
- {
- va_list ap;
- char text[COLS+1];
-
- var_start(ap,str);
- vsprintf(text,str,ap);
- addstr(text);
- va_end(ap);
- }
-
- #endif
-
- int
- get_chr_prompt FUN1(char *,prompt)
- {
- mvaddstr(input-1,0,prompt);
- clrtoeol();
- topclear=2;
- refresh();
- return get_chr();
- }
-
- void
- error_msg FUN1N(char *,str)
- {
- va_list foo;
- char buf[1000];
- /* Sigh. What I'd give for vprintw() */
-
- #ifdef TEST
- extern int isatty();
-
- if(!dbg_do_stderr)
- dbg_do_stderr= isatty(fileno(stderr)) ? 1 : 2;
- #endif
- var_start(foo,str);
- vsprintf(buf,str,foo);
- #ifdef TEST
- if(dbg_do_stderr==2) {
- fputs(buf,stderr);
- putc('\n',stderr);
- fflush(stderr);
- }
- #endif
- if(textout==2) {
- mvaddstr(input-1,COLS-7,"[MORE]");
- (void)get_chr();
- } else
- textout=2;
- mvaddstr(input-1,0,buf);
- clrtoeol();
- topclear=1;
- refresh();
- }
-
- void
- info_msg FUN1N(char *,str)
- {
- va_list foo;
- char buf[1000];
- /* See previous comment */
-
- var_start(foo,str);
- vsprintf(buf,str,foo);
- if(!status) {
- if(textout==2) {
- mvaddstr(input-1,COLS-7,"[MORE]");
- (void)get_chr();
- }
- textout=1;
- mvaddstr(input-1,0,buf);
- } else
- mvaddstr(status-1,0,buf);
- clrtoeol();
- refresh();
- }
- #ifndef amiga
-
- void
- _putchar FUN1(int, ch)
- {
- (void)putc(ch,stdout);
- /* (void)putchar(ch); */
- }
- #endif
-
- #ifndef __TURBOC__
- static void
- beep FUN0()
- {
- #ifdef SYSV
- _putchar('\007');
- #else
- static char *vb;
- static called;
-
- if(!called) {
- called++;
- vb=getcap("vb");
- }
- if(vb) {
- _puts(vb);
- } else {
- _putchar('\007');
- }
- #endif
- }
- #endif
-
- void
- shift_linked_window FUN2(long,dn, long,ov)
- {
- struct window *win;
-
- win=cwin;
- while(win->win_linked!=-1) {
- win= &wins[win->win_linked];
- if(win==cwin) /* Loop check! */
- return;
- if((win->win_flags&WIN_LCK_VT)==0)
- win->curow+=dn;
- if((win->win_flags&WIN_LCK_HZ)==0)
- win->cucol+=ov;
- if( win->curow<win->screen.lr || win->curow>win->screen.hr
- || win->cucol<win->screen.lc || win->cucol>win->screen.hc)
- recenter_window(win);
- }
- }
-
- int
- move_cell_cursor FUN2(CELLREF,rr, CELLREF,cc)
- {
- int ret;
- int cx,cy;
-
- if(cwin->win_linked!=-1)
- shift_linked_window((long)rr-curow,(long)cc-cucol);
- if( rr<cwin->screen.lr || rr>cwin->screen.hr
- || cc<cwin->screen.lc || cc>cwin->screen.hc) {
- cwin->curow=curow=rr;
- cwin->cucol=cucol=cc;
- recenter_window(cwin);
- disp_scrn();
- ret=1;
- } else {
- getyx(stdscr,cy,cx);
- hide_cell_cursor();
- curow=rr;
- cucol=cc;
- display_cell_cursor();
- cur_status();
- move(cy,cx);
- ret=0;
- }
- if(get_width(cucol)==0)
- find_nonzero_width(cwin);
- return ret;
- }
-
- static void
- find_nonzero_width FUN1(struct window *,win)
- {
- CELLREF cc;
- unsigned short n;
-
- cc=cucol;
-
- if(cc<win->screen.hc) {
- cc++;
- while((n=get_width(cc))==0) {
- if(cc==win->screen.hc)
- break;
- cc++;
- }
- if(n) {
- cucol=cc;
- return;
- }
- }
- if(cc>win->screen.lc) {
- --cc;
- while((n=get_width(cc))==0) {
- if(cc==win->screen.lc)
- break;
- --cc;
- }
- if(n) {
- cucol=cc;
- return;
- }
- }
- }
-
-
- void
- recenter_all_win FUN0()
- {
- int n;
-
- cwin->curow=curow;
- cwin->cucol=cucol;
- for(n=0;n<nwin;n++)
- recenter_window(&wins[n]);
- disp_scrn();
- }
-
- void
- recenter_cur_win FUN0()
- {
- cwin->curow=curow;
- cwin->cucol=cucol;
- recenter_window(cwin);
- disp_scrn();
- }
-
- static void
- recenter_window FUN1(struct window *,win)
- {
- CELLREF lr,hr,lc,hc;
- CELLREF rr;
- unsigned short w,ww;
- unsigned short n;
- unsigned short totwid = 0;
- int more;
-
- if(get_width(win->cucol)==0)
- find_nonzero_width(win);
-
- if(win->win_flags&WIN_PAG_VT) {
- lr=MIN_ROW+win->numr * ((win->curow-MIN_ROW)/win->numr);
- hr = (lr>MAX_ROW-win->numr) ? MAX_ROW : lr+win->numr-1;
- } else {
- rr=win->numr/2;
- lr= (win->curow<=rr) ? MIN_ROW : (win->curow-rr);
- if(lr>=MAX_ROW-win->numr) {
- hr=MAX_ROW;
- lr=hr+1-win->numr;
- } else
- hr=lr+win->numr-1;
- }
- set_numcols(win,hr);
-
- if(win->win_flags&WIN_PAG_HZ) {
- lc=hc=MIN_COL;
- w=get_width(hc);
- for(;;) {
- ww=get_width(hc+1);
- while(w+ww<=win->numc && hc<MAX_COL) {
- hc++;
- w+=ww;
- ww=get_width(hc+1);
- }
- if(hc>=win->cucol)
- break;
- hc++;
- lc=hc;
- w=ww;
- }
- if(lc>win->cucol || hc>MAX_COL) {
- error_msg("Can't find a non-zero-width column in recenter_window()");
- /* ... */
- }
- } else {
- lc=hc=win->cucol;
- n=totwid=get_width(win->cucol);
- do {
- if(lc>MIN_COL && totwid+(n=get_width(lc-1))<win->numc) {
- --lc;
- totwid+=n;
- more=1;
- } else
- more=0;
- if(hc<MAX_COL && totwid+(n=get_width(hc+1))<win->numc) {
- hc++;
- totwid+=n;
- more++;
- }
- } while(more);
- }
- while(get_width(lc)==0)
- lc++;
- while(get_width(hc)==0)
- --(hc);
-
- win->screen.lc=lc;
- win->screen.hc=hc;
- win->screen.lr=lr;
- win->screen.hr=hr;
- }
-
-
- int
- scroll_cell_cursor FUN1(int, magic)
- {
- int off_dn,off_rt;
- int n=0;
- int totwid;
-
- struct rng s;
- CELLREF cr,cc;
- unsigned short w;
- int over,down;
-
- over=colmagic[magic]*how_many;
- down=rowmagic[magic]*how_many;
- if(down) {
- off_dn=curow-cwin->screen.lr;
- n=down*cwin->numr;
- if(n>MAX_ROW-MIN_ROW) {
- error_msg(down>0 ? "Can't scroll down" : "Can't scroll up");
- return 0;
- }
- if(down>0) {
- if(cwin->screen.lr>MAX_ROW-n) {
- error_msg("Can't scroll down");
- return 0;
- }
-
- if(cwin->screen.hr>MAX_ROW-n) {
- s.hr=MAX_ROW;
- s.lr= (cwin->win_flags&WIN_PAG_VT) ? cwin->screen.lr+n : 1+s.hr-cwin->numr;
- cr= (off_dn>s.hr-s.lr) ? MAX_ROW : s.lr+off_dn;
- } else {
- s.lr=cwin->screen.lr+n;
- s.hr=cwin->screen.hr+n;
- cr=s.lr+off_dn;
- }
- } else {
- if(cwin->screen.hr<MIN_ROW-n) {
- error_msg("Can't scroll up");
- return 0;
- }
-
- if((cwin->win_flags&WIN_PAG_VT) && cwin->screen.hr==MAX_ROW) {
- s.lr=cwin->screen.lr+n;
- s.hr=s.lr+cwin->numr-1;
- } else if(cwin->screen.lr<MIN_ROW-n) {
- s.lr=MIN_ROW;
- s.hr=s.lr+cwin->numr-1;
- } else {
- s.lr=cwin->screen.lr+n;
- s.hr=cwin->screen.hr+n;
- }
- cr=s.lr+off_dn;
- }
-
- set_numcols(cwin,s.hr);
- } else {
- s.lr=cwin->screen.lr;
- s.hr=cwin->screen.hr;
- cr=curow;
- }
-
- off_rt=cucol-cwin->screen.lc;
-
- if(over>0) {
- if(cwin->screen.hc==MAX_COL) {
- error_msg("Can't scroll right");
- return 0;
- }
-
- for(s.lc=s.hc=cwin->screen.hc+1;;s.lc= ++s.hc) {
- --over;
- totwid=get_width(s.lc);
- while(s.hc<MAX_COL && totwid+(n=get_width(s.hc+1))<=cwin->numc) {
- s.hc++;
- totwid+=n;
- }
- if(!over || s.hc==MAX_COL)
- break;
- }
- if(!(cwin->win_flags&WIN_PAG_HZ)) {
- while(s.lc>MIN_COL && totwid+(n=get_width(s.lc-1))<=cwin->numc) {
- s.lc--;
- totwid+=n;
- off_rt++;
- }
- }
- cc= (s.hc-s.lc<off_rt) ? s.hc : s.lc+off_rt;
- } else if(over<0) {
- if(cwin->screen.lc==MIN_COL) {
- error_msg("Can't scroll left");
- return 0;
- }
-
- if(cwin->win_flags&WIN_PAG_HZ) {
- /* This is tricky! */
- int n_over;
- unsigned short ww = 0;
-
- n_over=0;
- for(s.lc=s.hc=MIN_COL,w=get_width(s.hc);
- ;
- s.lc= ++s.hc,w=ww,n_over++) {
- while(s.hc<MAX_COL && w+(ww=get_width(s.hc+1))<=cwin->numc) {
- s.hc++;
- w+=ww;
- }
- if(s.hc>=cucol)
- break;
- }
- n_over+=over;
- if(n_over<0) {
- error_msg("Can't scroll left");
- return 0;
- }
-
- for(s.lc=s.hc=MIN_COL,w=get_width(s.hc);
- ;
- s.lc=s.hc+1,s.hc++,w=ww) {
- ww=get_width(s.hc+1);
- while(w+ww<=cwin->numc && s.hc<MAX_COL) {
- s.hc++;
- w+=ww;
- ww=get_width(s.hc+1);
- }
- if(!n_over--)
- break;
- }
- over=0;
- cc= (s.hc-s.lc<off_rt) ? s.hc : s.lc+off_rt;
- } else {
- for(s.lc=s.hc=cwin->screen.lc-1;;s.hc= --s.lc) {
- over++;
- totwid=get_width(s.lc);
- while(s.lc>MIN_COL && totwid+(n=get_width(s.lc-1))<=cwin->numc) {
- s.lc--;
- totwid+=n;
- }
- if(!over || s.lc==MIN_COL)
- break;
- }
- if(s.lc==MIN_COL) {
- while(s.hc<MAX_COL && totwid+(n=get_width(s.hc+1))<=cwin->numc) {
- s.hc++;
- totwid+=n;
- }
- }
- cc= (s.hc-s.lc<off_rt) ? s.lc : s.lc+off_rt;
- }
- } else if(!(cwin->win_flags&WIN_PAG_HZ)) {
- /* If page_scroll, we don't have to bother with this.
- It'll fit. That's all. . . */
- totwid=0;
- s.lc=cwin->screen.lc;
- s.hc=cwin->screen.hc;
- cc=cucol;
-
- /* This is tricky: ;n<=s.hc; won't work if s.hc==MAX_CELLREF */
- for(n=s.lc;;n++) {
- totwid+=get_width(n);
- if(n==s.hc)
- break;
- }
- while(cwin->numc<totwid) {
- if(cucol==s.lc)
- totwid-=get_width(s.hc--);
- else
- totwid-=get_width(s.lc++);
- }
- while(s.hc<MAX_COL && totwid+(n=get_width(s.hc+1))<=cwin->numc) {
- ++s.hc;
- totwid+=n;
- }
- while(s.lc>MIN_COL && totwid+(n=get_width(s.lc-1))<=cwin->numc) {
- --s.lc;
- totwid+=n;
- }
- } else {
- cwin->screen.lr=s.lr;
- cwin->screen.hr=s.hr;
- if(cwin->win_linked!=-1)
- shift_linked_window((long)cr-curow,(long)0);
- curow=cr;
- disp_scrn();
- return 1;
- }
-
- if(over) {
- error_msg(over>0 ? "Can't scroll right" : "Can't scroll left");
- return 0;
- }
-
- while(get_width(s.lc)==0)
- s.lc++;
- while(get_width(s.hc)==0)
- --(s.hc);
-
- if(cwin->win_linked!=-1)
- shift_linked_window((long)cr-curow,(long)cc-cucol);
-
- cwin->screen=s;
- curow=cr;
- cucol=cc;
-
- if(get_width(cc)==0)
- find_nonzero_width(cwin);
-
- disp_scrn();
- return 1;
- }
-
- void
- read_mp_windows FUN1(char *,line)
- {
- int wnum=0;
- char *text;
- CELLREF nrow=NON_ROW,ncol=NON_COL;
- char *split=0;
- char *opts=0;
- struct window *win;
-
- text=line;
- for(;;) {
- switch(*text++) {
- /* Window Number */
- case 'N':
- wnum=astol(&text);
- break;
- /* Cursor At */
- case 'A':
- nrow=astol(&text);
- ncol=astol(&text);
- break;
- /* JF: Window options */
- case 'O':
- opts=text;
- while(*text && *text!=';')
- text++;
- break;
- /* Split into two windows */
- case 'S':
- split=text;
- while(*text && *text!=';')
- text++;
- break;
- /* Set Colors NOT supported */
- case 'C':
- while(*text && *text!=';')
- text++;
- break;
- /* Alternate border NOT supported. . . */
- case 'B':
- break;
- default:
- --text;
- break;
- }
- if(*text=='\0' || *text=='\n')
- break;
- if(*text!=';') {
- char *bad;
-
- bad=text;
- while(*text && *text!=';')
- text++;
- if(*text)
- *text++='\0';
- error_msg("Unknown SYLK window cmd: %s",bad);
- if(!*text)
- break;
- } else
- *text++='\0';
- }
- if(wnum<1 || wnum>nwin) {
- error_msg("Window %d out of range in SYLK line %s",wnum,line);
- return;
- }
- --wnum;
- win= &wins[wnum];
- if(nrow!=NON_ROW) {
- win->curow=nrow;
- win->cucol=ncol;
- if(win==cwin) {
- curow=nrow;
- cucol=ncol;
- }
- recenter_window(win);
- }
- if(split) {
- int hv = 0;
- int where;
- int link;
- struct window *new;
-
- switch(*split++) {
- case 'H':
- case 'h':
- hv=1;
- break;
- case 'v':
- case 'V':
- hv=0;
- break;
- case 't':
- case 'T':
- error_msg("Window split titles not supported");
- return;
- default:
- break;
- }
- if(*split=='L') {
- link=wnum;
- split++;
- } else
- link= -1;
-
- where=astol(&split);
-
- if(hv ? where>=win->numr : where>=win->numc)
- error_msg("Can't split window: screen too small");
-
- nwin++;
-
- wins=ck_realloc(wins,nwin*sizeof(struct window));
- cwin=wins;
- win= &wins[wnum];
- new= &wins[nwin-1];
-
- win->numc-=(hv ? 0 : where);
- win->numr-=(hv ? where : 0);
- win->curow=curow;
- win->cucol=cucol;
-
- new->win_flags = WIN_EDGES|WIN_EDGE_REV;/* Mplan defaults */
- new->lh_wid=0; /* For now */
- new->win_linked=link;
-
- new->win_over=win->win_over + (hv ? -win->lh_wid : win->numc);
- new->win_down=win->win_down + (hv ? win->numr+1 : 0);
- new->numc=(hv ? win->numc+win->lh_wid : where);
- new->numr=(hv ? where-1 : win->numr);
- new->curow=curow;
- new->cucol=cucol;
- set_numcols(new,curow);
- recenter_window(win);
- recenter_window(new);
- }
- if(opts) {
- char *np;
-
- while(np=index(opts,',')) {
- *np='\0';
- set_options(opts);
- *np++=';';
- opts=np;
- }
- if(np=rindex(opts,'\n'))
- *np='\0';
- set_options(opts);
- }
- }
-
- void
- write_mp_windows FUN1(FILE *,fp)
- {
- int n;
- char buf[90];
-
- cwin->curow=curow;
- cwin->cucol=cucol;
- fprintf(fp,"O;status %d\n",status);
- if(nwin>1) {
- /* ... */
- }
- for(n=0;n<nwin;n++) {
- buf[0]='\0';
- if(wins[n].win_flags&WIN_LCK_HZ)
- strcat(buf,",lockh");
- if(wins[n].win_flags&WIN_LCK_VT)
- strcat(buf,",lockv");
- if(wins[n].win_flags&WIN_PAG_HZ)
- strcat(buf,",pageh");
- if(wins[n].win_flags&WIN_PAG_VT)
- strcat(buf,",pagev");
- if(wins[n].win_flags&WIN_EDGE_REV)
- strcat(buf,",standout");
- if((wins[n].win_flags&WIN_EDGES)==0)
- strcat(buf,",noedges");
- fprintf(fp,"W;N%d;A%u %u;C%d %d %d;O%s\n",n+1,wins[n].curow,wins[n].cucol,7,0,7,buf+1);
- }
- }
-